package com.xiaolei.fastnio.http.Adapter

import com.xiaolei.fastnio.http.*
import com.xiaolei.fastnio.http.Comm.HttpStatus
import com.xiaolei.fastnio.http.Protocol.RequestProtocol
import com.xiaolei.fastnio.library.Adapters.Impls.ProtocolClientAdapter
import com.xiaolei.fastnio.library.Client.Session
import java.lang.Exception
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.LinkedBlockingQueue

/**
 * 空闲的Response类
 */
private val idleResponse = LinkedBlockingQueue<Response>()

/**
 * 所有网络请求处调配中心
 */
open class HttpClientAdapter(private val uriMapper: ConcurrentHashMap<String, LinkedList<Route>>,
                             private val indexUri: String) : ProtocolClientAdapter<Request, RequestProtocol>(RequestProtocol::class)
{
    private var response: Response? = null

    /**
     * 启动会话，从空闲response中取出已有response
     */
    override fun onSessionCreate(session: Session)
    {
        response = (idleResponse.poll() ?: Response()).apply {
            this.session = session
        }
    }

    /**
     * 会话结束，回收清理Response资源
     */
    override fun onSessionClose(session: Session)
    {
        response?.let { response ->
            response.onClear()
            idleResponse.offer(response)
        }
        response = null
    }

    override fun onSessionReceive(session: Session, request: Request)
    {
        val response = response ?: return
        val routes = uriMapper[if (request.uri == "/") indexUri else request.uri]
        request.response = response
        if (routes != null)
        {
            try
            {
                val route = routes.firstOrNull { it.method.name == request.method }
                if (route == null)
                {
                    response.status = HttpStatus.METHOD_NOT_ALLOW
                    response.message = "${request.uri} ${request.method} 不被支持"
                    response.writeHtml("""
                        <html>
                            <body>${response.message}</body>
                        </html>
                    """.trimIndent())
                } else
                {
                    route.onRoute.invoke(request, response)
                }
            } catch (e: Exception)
            {
                e.printStackTrace()
                response.status = HttpStatus.SERVER_ERROR
                response.message = "服务器内部错误"
            }
        } else
        {
            response.status = HttpStatus.NOT_FOUND
            response.message = "404 ${request.uri} 网页未找到"
            response.writeHtml("""
                <html>
                    <body>${response.message}</body>
                </html>
            """.trimIndent())
        }
        response.flush()
        response.close()
    }
}